<template>
  <view class="chat-container">
    <u-navbar
      v-if="options.showTitle == 1"
      id="server-navbar"
      :title="options.title"
      auto-back
      fixed
      placeholder
    ></u-navbar>

    <!-- 聊天消息列表区域  -->
    <!-- 
      scroll-view 备用 （定位消息有问题，未解决）
      scroll-y
      :scroll-top="scrollTop"
      :scroll-with-animation="true"
      :show-scrollbar="false"
      @scrolltoupper="loadMore" -->
    <view class="chat-list">
      <serviceList
        :list="servicers"
        :fixed="true"
        :topStickyHeight="topStickyHeight"
        @refresh="handleRefreshServiceList"
      />
      <customCyzx v-if="pluginStatus.customCyzx" />
      <!-- <wecatInfo v-if="pluginStatus.wecatInfo" /> -->
      <commonProblem v-if="pluginStatus.commonProblem" @select="handleProblemSelect" />
      <serviceRecommed v-if="pluginStatus.serviceRecommed" />

      <u-loadmore v-if="messageList.length > 0 && msgLoadStatus != 'nomore'" :status="msgLoadStatus" />

      <messageItem v-for="(item, index) in messageList" :key="item.messageID || index" :message="item" />

      <view id="sign-end" style="height: 100rpx; width: 100rpx"></view>
    </view>

    <!-- 底部输入区域 -->
    <view class="input-area">
      <!-- 预发送信息 -->
      <view class="preMsg" v-if="options?.preMsg?.sendSigin === false">
        <view class="preMsg-title">携带的服务信息，是否发送给客服人员？</view>
        <view class="preMsg-msg">
          <u-parse :content="options?.preMsg?.richText"></u-parse>
        </view>
        <view class="flex justify-end">
          <view class="preMsg-btn preMsg-cancel" @click="options.preMsg.sendSigin = true">取消</view>
          <view class="preMsg-send preMsg-btn" @click="sendPreMessage">发送</view>
        </view>
      </view>

      <chatInput
        ref="chatInputRef"
        @send-message="handleSendMessage"
        @send-image="handleSendImage"
        @send-voice="handleSendVoice"
        @send-video="handleSendVideo"
        @send-wecat-info="handleSendWecatInfo"
        @debug="handleDebug"
      >
      </chatInput>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive, nextTick } from "vue";
import messageItem from "../components/message-item.vue";
import chatInput from "../components/chat-input.vue";
import wecatInfo from "../components/wecat-info.vue";
import commonProblem from "../components/common-problem.vue";
import serviceRecommed from "../components/service-recommed.vue";
import serviceList from "../components/service-list.vue";
import customCyzx from "../components/custom-cyzx.vue";
// import wkImUtils from "../utils";
import WKSDK, { SendackPacket, type Message, ConnectStatus } from "wukongimjssdk";
import { convertMessage, debounce /* , getUrlParams, objToUrlParams */ } from "../utils/utils";
import { onLoad } from "@dcloudio/uni-app";
import Base64 from "base-64";
import KOCSIM from "../initKOCSIM";
import listenLineUp from "../utils/service/line-up";

const pluginStatus = reactive({
  wecatInfo: true,
  commonProblem: true,
  serviceRecommed: false,
  serviceList: true,
  customCyzx: false,
});

const messageList = reactive([
  /* testMsg */
]);

const scrollTop = ref(0);

const msgLoadStatus = ref("nomore");

// 坐席列表
const servicers = ref([]);

// 预发信息
const sendPreMessage = () => {
  handleSendMessage(options.value.preMsg.richText);
  options.value.preMsg.sendSigin = true; // 发送预发信息后，将预发信息标记为已发送
};

// 发送文本消息
const handleSendMessage = (content: string) => {
  KOCSIM.inst().sendMessage({
    type: 1,
    content: content,
  });
};

// 发送图片消息
const handleSendImage = (file: any) => {
  KOCSIM.inst().sendMessage({
    type: 2,
    content: file.path,
  });
};

// 发送语音消息
const handleSendVoice = (voice: any) => {
  KOCSIM.inst().sendMessage({
    type: 3,
    content: voice,
  });
};

// 发送视频消息
const handleSendVideo = (video: any) => {
  KOCSIM.inst().sendMessage({
    type: 4,
    content: video,
  });
};

// 发送微信公众/公司信息
const handleSendWecatInfo = (content: string) => {
  addMessage({
    type: "wecat-info",
    content: content,
    from: "system",
  });
  // wkImUtils.sendMessage({
  //   type: 101,
  //   content: content,
  //   from: "system",
  // });
};

// 调试/测试
const handleDebug = (data: any) => {
  console.log("handleDebug data", data);
  if (data.type === "debug-test-dynamic-update-list") {
    // 测试更新 一条消息的状态
    let thatmsg;
    for (let i = messageList.length - 1; i > 0; i--) {
      if (messageList[i].contentType < 5) {
        thatmsg = messageList[i];
        break;
      }
    }

    if (thatmsg.type === "text") {
      thatmsg.content = {
        text: "测试更新 一条消息的状态" + new Date().getTime(),
      };
    }
    thatmsg.status = thatmsg.status == "send-fail" ? "upload" : "send-fail";
  }
};

// 选择常见问题
const handleProblemSelect = (item: any) => {
  console.log("handleProblemSelect item", item);

  // 添加本地消息
  addMessage({
    type: "text",
    content: { text: item.title },
    from: "user",
    time: new Date().getTime(),
  });
  addMessage({
    type: "text",
    content: { text: item.content },
    from: "service",
    time: new Date().getTime(),
  });
};

// 添加消息到列表
const addMessage = (message: any) => {
  // console.log("addMessage >>", message);
  messageList.push({ ...message });
  scrollToBottom();
  return messageList.length - 1;
};

// 滚动到底部
const scrollToBottom = debounce(() => {
  nextTick(() => {
    uni.pageScrollTo({
      scrollTop: 99999,
      duration: 100,
    });
    // 定义了一个标记元素，获取其位置，然后滚动到该位置
    // uni
    //   .createSelectorQuery()
    //   .select("#sign-end")
    //   .boundingClientRect((res: any) => {
    //     console.log("boundingClientRect", res);
    //     scrollTop.value = res.top;
    //     uni.pageScrollTo({
    //       scrollTop: 99999 /* res.top */,
    //       duration: 100,
    //     });
    //   })
    //   .exec();
  });
}, 500);

// 加载更多历史消息
const loadMore = async () => {
  // 实现加载历史消息的逻辑
  console.log("loadMore");
  // const channelId = wkImUtils.currentChannel.channelID;
  // const isLoadMore = true;
  // if (!channelId) {
  //   return;
  // }
  // // 获取最前面的消息的顺序
  // const firstMessageSeq = messageList.length > 0 ? messageList[0].seq : 0;
  // const { data, success } = await getChannelMessagesById({
  //   channelId: channelId,
  //   endMessageSeq: 0,
  //   limit: 20,
  //   // 拉取模式 0:向下拉取 1:向上拉取
  //   pullMode: 1,
  //   // 开始消息列号，默认值0
  //   startMessageSeq: isLoadMore ? messageList.length : 0,
  //   // 当前登录用户uid
  //   loginUid: WKSDK.shared().config.uid,
  // });
  // if (success && data.messages) {
  //   const messages = data.messages.map((item: any) => {
  //     // 解码
  //     const payload = Base64.decode(item.payload);
  //     const decodePayload = utf8.decode(payload);
  //     const content = JSON.parse(decodePayload);
  //     return convertMessage({
  //       // TODO 目前只支持文本消息
  //       ...item,
  //       content: {
  //         text: content.content,
  //         contentType: content.type,
  //       },
  //       channel: {
  //         channelId: item.channelId,
  //         channelType: item.channelType,
  //       },
  //       contentType: 1,
  //     });
  //   });
  //   if (data.more === 0) {
  //     msgLoadStatus.value = "nomore";
  //   } else {
  //     msgLoadStatus.value = "loadmore";
  //   }
  //   if (isLoadMore) {
  //     // 前面插入
  //     messageList.value = messages.concat(messageList.value);
  //   } else {
  //     messageList.value = messages;
  //     scrollToBottom();
  //   }
  // }
};

// 刷新客服列表
const handleRefreshServiceList = () => {
  servicers.value = [];
  console.log("handleRefreshServiceList");
  // 获取在线客服列表
  KOCSIM.inst()
    .getOnlineServiceList()
    .then((res) => {
      console.log("getOnlineServiceList res", res);
      servicers.value = res;
    });
};

/**
 * 悟空通讯sdk
 */

// 事件
const onMessage = (message: Message) => {
  console.log("onMessage >> ", message);
  addMessage(convertMessage(message));
  /** 其他逻辑 */
  // 1 结束会话时，发送客服评价
  if (message.contentType === 2101) {
    console.log("结束会话时，发送客服评价");
    // 发送客服评价
    uni.$emit("sendLocalMsg", {
      type: "rate",
      content: {
        text: "客服评价",
      },
      from: "service",
      time: new Date().getTime(),
    });
    // 结束会话 清除状态等
    KOCSIM.inst().endChannel();
    // 发送连接状态变更
    uni.$emit("KN-IM:connect-status", "disconnected");
    // 清除排队监听 （可能残留）
    listenLineUp.destroy();
  }
  // 2 客服接入
  if (message.contentType === 2102) {
    console.log("客服接入");
    // 清除排队监听
    listenLineUp.destroy();
  }
};
const onMessageStatusChange = (packet: SendackPacket) => {
  if (packet.reasonCode === 1) {
    // 发送成功
    console.log("消息发送成功");
  } else {
    // 发送失败
    console.log("消息发送失败");
  }
};

const onMessageAsync = async (message: Message) => {
  addMessage(convertMessage(message));
}

const initPage = async () => {
  if (!KOCSIM.inst().initStatus) {
    // 初始化
    await KOCSIM.inst().init();
    // 登录用户
    KOCSIM.inst().login();
  }
  // 设置当前页面需要监听的事件
  // 监听消息变化
  WKSDK.shared().chatManager.addMessageListener(onMessage);
  // 监听消息发送状态
  WKSDK.shared().chatManager.addMessageStatusListener(onMessageStatusChange);
  // 设置通道消息更新监听
  KOCSIM.inst().setOnMessageAsync(onMessageAsync);

  /**
   * 获取会话配置
   *  如果 设置自选客服，则获取在线客服列表，并支持点击客服进行咨询 和 直接发送消息咨询
   *  如果 设置自动客服，则此处不获取在线客服列表，在发送消息时再创建与客服的会话
   */
  await KOCSIM.inst().syncKfConvSetting({ dataType: 4 });
  if (KOCSIM.inst().kfConversationSetting.isChoose) {
    // 获取在线客服列表
    await KOCSIM.inst()
      .getOnlineServiceList({ onlineStatus: 1 })
      .then((res) => {
        console.log("getOnlineServiceList res", res);
        servicers.value = res;
      });
  }
};

const options = ref<AnyObject>({
  uid: "", // 用户id
  title: "在线客服", // 标题
  showTitle: 1, // 是否显示标题
  type: "", // 类型，CYZX
  preMsg: {
    title: "", // 前置消息内容
    lable: "",
    type: "link",
    url: "",
  },
});

onLoad((opts: AnyObject = {}) => {
  console.log("onLoad options", opts);
  if (opts?.preMsg && typeof opts.preMsg === "string") {
    try {
      // 移除转义
      opts.preMsg = JSON.parse(Base64.decode(opts.preMsg));

      opts.preMsg.title = decodeURIComponent(opts.preMsg.title);
      opts.preMsg.lable = decodeURIComponent(opts.preMsg.lable);
      opts.preMsg.sendSigin = false;
      if (opts.preMsg?.type === "link") {
        opts.preMsg.richText = `<a href="${opts.preMsg.url}"  target="_blank">
        <h4>${opts.preMsg.title}</h4>
        <p>${opts.preMsg.lable}</p>
        <img src="${opts.preMsg.image}" width="180px" height="80px"  />`;
      }
    } catch (error) {
      console.error("preMsg JSON.parse error", error);
    }
  }
  // options.value = opts;
  Object.assign(options.value, opts);
  // #ifdef H5
  // 设置网页标题
  uni.setNavigationBarTitle({
    title: options.value.title || "在线客服",
  });
  // #endif

  // 初始化悟空通讯sdk
  initPage();

  // 其他暂时逻辑
  if (options.value.type === "CYZX") {
    pluginStatus.customCyzx = true;
    pluginStatus.commonProblem = false;
    pluginStatus.serviceRecommed = false;
    pluginStatus.serviceList = true;
    pluginStatus.wecatInfo = false;
  }
});

let topStickyHeight = ref(10);

onMounted(() => {
  console.log("onMounted");
  // 查询顶部 sticky 高度
  uni
    .createSelectorQuery()
    .select("#server-navbar")
    .boundingClientRect((res: any) => {
      console.log("#server-navbar Rect", res);
      if (res?.height) {
        topStickyHeight = res.height;
      }
    })
    .exec();

  // 监听其他页面控制发送本地消息
  uni.$on("sendLocalMsg", (msg: AnyObject) => {
    addMessage(msg);
  });
});

onUnmounted(() => {
  // 移除消息监听
  WKSDK.shared().chatManager.removeMessageListener(onMessage);
  // 移除消息发送状态监听
  WKSDK.shared().chatManager.removeMessageStatusListener(onMessageStatusChange);
  // 如果需要离开页面不再连接，执行断开连接
  // WKSDK.shared().connectManager.disconnect();
  
  // 移除监听其他页面控制发送本地消息
  uni.$off("sendLocalMsg");
});
</script>

<style lang="scss" scoped>
/* 客服聊天图标 */
// @import url("./static/css/chatIcon.scss");

.chat-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background-color: #f5f5f5;
  // background-color: black;
  position: relative;
  box-sizing: border-box;
}

.chat-list {
  flex: 1;
  padding: 20rpx;
  // overflow-y: auto;
  // -webkit-overflow-scrolling: touch;
  // box-sizing: border-box;
}

.input-area {
  background-color: #fff;
  border-top: 1rpx solid #eee;
  padding-bottom: env(safe-area-inset-bottom);
  position: sticky;
  bottom: 0;
  z-index: 1;
  transition: all 0.5s;

  .preMsg {
    position: absolute;
    bottom: calc(env(safe-area-inset-bottom) + 100% + 20rpx);
    right: 20rpx;
    background-color: white;
    padding: 10rpx 20rpx;
    border-radius: 10rpx;
    box-shadow: -5rpx 5rpx 30rpx lightgray;
    z-index: 3;

    .preMsg-title {
      font-size: 25rpx;
    }

    .preMsg-btn {
      font-size: 25rpx;
      border-radius: 10rpx;
      display: flex;
      justify-content: center;
      width: fit-content;
      padding: 5rpx 20rpx;
      justify-self: flex-end;
      margin-top: 10rpx;
      color: #7c7c7c;
      background: #eeeeee;

      &.preMsg-send {
        background-color: #ffcb6c;
        color: white;
      }

      &.preMsg-cancel {
        color: #7c7c7c;
        background: #eeeeee;
        margin-right: 10rpx;
      }
    }
  }
}
</style>
